import { useCallback, useMemo, useState } from "react";

/**
 * The canvas count is used to generate a unique Unity canvas ID.
 */
let unityCanvasCount = 0;

/**
 * The prefix used to generate a unique Unity canvas ID.
 */
const canvasIdPrefix = "react-unity-webgl-canvas";

/**
 * Generates a unique Unity canvas ID. This is used internally by Unity since
 * version 2021.2 to identify the canvas element in the DOM. This is not
 * documented in the Unity documentation, but it is used in the Unity source
 * code.
 * @returns A unique identifier for a Unity canvas element.
 */
const useCanvasIdentifier = (id?: string): [string, VoidFunction] => {
  /**
   * The canvas incremention is used to generate a new unique Unity canvas ID.
   */
  const [canvasIncremention, setCanvasIncremention] = useState(0);

  /**
   * Refreshes the canvas ID by incrementing the canvas incremention.
   */
  const refreshCanvasId = useCallback(() => {
    // The canvas incremention is used to generate a new unique Unity canvas ID.
    setCanvasIncremention((prev) => prev + 1);
  }, []);

  // If the user has provided a Unity canvas ID, then this value is returned.
  // This is useful for when the user wants to use a custom canvas ID.
  if (id !== undefined) {
    return [id, refreshCanvasId];
  }

  /**
   * A unique identifier for a Unity canvas element is memorized.
   */
  const canvasId = useMemo(() => {
    // The Unity canvas ID is generated by concatenating the Unity canvas ID
    // prefix with the canvas count. Every time this value is requested, the
    // canvas count is incremented.
    return [canvasIdPrefix, unityCanvasCount].join("-");
  }, [canvasIncremention]);

  return [canvasId, refreshCanvasId];
};

export { useCanvasIdentifier };
